/*
 * gui.c
 * This file is part of COOG
 *
 * Copyright (C) 2012 - Luke William Westby & Jon Gautsch
 *
 * lab10 is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * lab10 is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with lab10. If not, see <http://www.gnu.org/licenses/>.
 */

#include "synth.h"

// the functions in gui.c are pretty self-explanatory. lots and lots of geometry
// and calls to gfx_line in order to produce the desired output. 

void draw_piano_roll(double xOrigin, double yOrigin){
    
    int i, key_width = 30, key_height = 150, num_keys = 14;
    
    gfx_color(0, 150, 0);
    
    draw_white_keys(xOrigin, yOrigin, key_width, key_height, num_keys);
    draw_black_keys(xOrigin, yOrigin, key_width, key_height, num_keys);
}


void draw_white_keys(double xOrigin, double yOrigin, int key_width, int key_height, int num_keys){

    int i;
    
    gfx_line(xOrigin, yOrigin, xOrigin + num_keys*key_width, yOrigin);
    gfx_line(xOrigin, yOrigin - key_height, xOrigin + num_keys*key_width, yOrigin - key_height);
    gfx_line(xOrigin, yOrigin, xOrigin, yOrigin - key_height);
    gfx_line(xOrigin + key_width*num_keys, yOrigin, xOrigin + key_width*num_keys, yOrigin - key_height);
    
    for (i = 1; i <= num_keys; i++) {
        gfx_line(xOrigin + i*key_width, yOrigin, xOrigin + i*key_width, yOrigin - key_height);
    }
}


void draw_black_keys(double xOrigin, double yOrigin, int key_width, int key_height, int num_keys){
    
    int i, j;
    
    for (i = 0; i < 14; i++) {
        
        if(!(i == 2 || i == 6 || i == 9 || i == 13 || i == 16 || i == 20 || i == 23)){
    
            for (j = 0; j < .666666*key_width; j++) {
                
                
                
                gfx_line(xOrigin + .6666666*key_width + key_width*i + j, yOrigin - key_height, xOrigin + .666666*key_width + key_width*i + j, yOrigin - .3333*key_height);
        
            }
        }
    }
    
    label_keys(xOrigin, yOrigin, key_width, key_height, num_keys);
}


void draw_waveform_boxes(int x, int y){
    int box_length = 190, box_height = 70, i, holdx = x, holdy = y;
    
    
    
    for (i = 0; i < 3; i++) {
    
        gfx_line(x, y, x + box_length, y);
        gfx_line(x, y+box_height, x + box_length, y + box_height);
        gfx_line(x, y, x, y + box_height);
        gfx_line(x + box_length, y, x + box_length, y + box_height);
        y += box_height + 40;
    }
    
    draw_waveforms(holdx, holdy + box_height/2, box_length, box_height);
}


void draw_waveforms(int x, int y, int box_length, int box_height){
    
    int holdx = x, holdy = y;
    double theta;
    
    // draw the sine wave
    for (theta = 0; theta < box_length; theta+=.1) {
        gfx_line(x + theta, y + 20*sin((theta)/12), x + theta + .1, y + 20*sin((theta+.1)/12));
    }
    
    y += box_height + 40;
    
    // draw the sawtooth wave
    gfx_line(x, y, x + 50, y + box_height*.3);
    gfx_line(x + .25*box_length, y + box_height*.3, x + .25*box_length, y - box_height*.3);
    gfx_line(x + .25*box_length, y - box_height*.3, x + .75*box_length, y + box_height*.3);
    gfx_line(x + .75*box_length, y + box_height*.3, x + .75*box_length, y - box_height*.3);
    gfx_line(x + .75*box_length, y - box_height*.3, x + box_length, y);
    
    y += box_height + 40;
    
    // draw the square wave
    gfx_line(x, y + box_height*.3, x + 20, y + box_height*.3);
    gfx_line(x + 20, y + box_height*.3, x + 20, y - box_height*.3);
    gfx_line(x + 20, y - box_height*.3, x + 60, y - box_height*.3);
    gfx_line(x + 60, y - box_height*.3, x + 60, y + box_height*.3);
    gfx_line(x + 60, y + box_height*.3, x + 100, y + box_height*.3);
    gfx_line(x + 100, y + box_height*.3, x + 100, y - box_height*.3);
    gfx_line(x + 100, y - box_height*.3, x + 140, y - box_height*.3);
    gfx_line(x + 140, y - box_height*.3, x + 140, y + box_height*.3);
    gfx_line(x + 140, y + box_height*.3, x + 180, y + box_height*.3);
    gfx_line(x + 180, y + box_height*.3, x + 180, y - box_height*.3);
    gfx_line(x + 180, y - box_height*.3, x + box_length, y - box_height*.3);
}


void label_keys(double xOrigin, double yOrigin, int key_width, int key_height, int num_keys){
    
    char letters_for_white_keys_in_order[24] = {"qetyipsdgjkzcb"};
    char letters_for_black_keys_in_order[24] = {"wr uoa fh lxv"};
    char temp;
    int i = 0, j, x;
    
    // Label the white keys
    for (i = 0; i < num_keys; i++){
        x = xOrigin + i*key_width + key_width*.3 + 2;
        temp = letters_for_white_keys_in_order[i];
        letter(x, yOrigin - .25*key_height, temp, 1);
    }
    
    gfx_color(0,0,0); // Paint it black
    
    // Label the black keys
    for (i = 0; i < strlen(letters_for_black_keys_in_order); i++) {
        x = xOrigin + i*key_width + key_width*.3 + 17;
        temp = letters_for_black_keys_in_order[i];
        letter(x, yOrigin - .5*key_height, temp, 1);
        
    }
}

void draw_wave_selection_numbers(double xOrigin, double yOrigin, int size){
    
    
    gfx_color(0, 150, 0);
    
    draw_one(xOrigin, yOrigin, size);
    yOrigin += 120;
    draw_two(xOrigin, yOrigin, size);
    yOrigin += 120;
    draw_three(xOrigin, yOrigin, size);
}

void draw_one(int x, int y, int size){
    
    gfx_line(x, y, x+(size*.5), y);
    gfx_line(x+(size*.25), y, x+(size*.25), y-size);
    gfx_line(x+(size*.25), y-size, x, y-(size*.95));
    gfx_flush();
    
}//end draw_one

void draw_two(int x, int y, int size){
    
    gfx_line(x, y, x+(size*.5), y);
    gfx_line(x, y, x+(size*.5), y-(size*.75));
    draw_curve(x+(size*.25), y-(size*.75), size*.25, M_PI, 6*M_PI/3);
    gfx_flush();
    
}//end draw_two

void draw_three(int x, int y, int size){
    
    draw_curve(x+(size*.25), y-(size*.75), size*.25, -5*M_PI/6, M_PI/2);
    draw_curve(x+(size*.25), y-(size*.25), size*.25, -M_PI/2, 5*M_PI/6);
    gfx_flush();
    
}//end draw_three

void draw_curve(int x, int y, int r, double alpha, double beta){
    
    double theta;
    for (theta = alpha; theta <= beta; theta += .01) {
        gfx_line(x+r*cos(theta),y+r*sin(theta),x+r*cos(theta+.01),y+r*sin(theta+.01));
    }
}
